package net.soevar.common;

import java.io.Serializable;
import java.util.Date;
import java.util.List;

import net.soevar.action.master.helper.ChangePasswordWindow;
import net.soevar.database.hibernate.HibernateUtil;
import net.soevar.database.model.AthMenu;
import net.soevar.database.model.AthRole;
import net.soevar.database.model.AthUser;
import net.soevar.database.model.CommonVO;
import net.soevar.database.model.Jobseeker;
import net.soevar.ui.util.MyIframe;

import org.apache.log4j.Logger;
import org.hibernate.Criteria;
import org.hibernate.EntityMode;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.hibernate.metadata.ClassMetadata;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Sessions;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.sys.ExecutionsCtrl;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zul.Combobox;
import org.zkoss.zul.Comboitem;
import org.zkoss.zul.Messagebox;
import org.zkoss.zul.Paging;
import org.zkoss.zul.South;
import org.zkoss.zul.Tab;
import org.zkoss.zul.Tabbox;
import org.zkoss.zul.Tabpanel;
import org.zkoss.zul.Window;

public class Common {
	private static Logger log = Logger.getLogger(Common.class);
	/*** FOR VARIABLE ***/
	public static String ROOT = "/st";
	public static String REAL_PATH = "http://localhost:8080/st/";

	public static int MAX_RESULT = 100;
	public static int MAX_RESULT_100 = 100;
	public static int MAX_RESULT_50 = 50;
	public static int MAX_RESULT_20 = 20;
	public static int MAX_RESULT_300 = 300;
	public static int MAX_RESULT_500 = 500;
	public static int ROWS_COUNT_ON_PAGE = 10;
	public static final String DES_PASS_PHRASE = "CARIER_CENTER";
	public static DesEncrypter desEncrypter = new DesEncrypter(
			Common.DES_PASS_PHRASE);

	/*** FOR SESSION ***/
	public static void goLogoff() {
		ExecutionsCtrl.getCurrent().sendRedirect("/logoff");
	}

	public static AthUser getCurrentUser() {
		AthUser users = (AthUser) Sessions.getCurrent().getAttribute(
				"usersTemp");
		return users;
	}

	public static AthMenu getCurrentMenu() {
		AthMenu menu = (AthMenu) Sessions.getCurrent().getAttribute(
				"currentMenu");
		return menu;
	}

	public static AthUser getCurrentFromSpringUser() {
		Object principal = SecurityContextHolder.getContext()
				.getAuthentication().getPrincipal();
		UserDetails userDetails = null;
		if (principal instanceof UserDetails) {
			userDetails = (UserDetails) principal;
		}
		String userName = userDetails.getUsername();

		Jobseeker jobseeker = (Jobseeker) HibernateUtil.currentSession()
				.createCriteria(Jobseeker.class)
				.add(Restrictions.eq("jobseekerId", userName)).setMaxResults(1)
				.uniqueResult();
		if (jobseeker == null) {
			AthUser users = (AthUser) HibernateUtil.currentSession()
					.createCriteria(AthUser.class)
					.add(Restrictions.eq("userId", userName)).setMaxResults(1)
					.uniqueResult();
			Sessions.getCurrent().setAttribute("usersTemp", users);
			return users;
		} else {
			AthRole athrole = (AthRole) HibernateUtil.currentSession()
					.createCriteria(AthRole.class)
					.add(Restrictions.eq("roleId", "jobseeker"))
					.setMaxResults(1).uniqueResult();
			System.out.println(athrole);
			AthUser users = new AthUser();
			users.setJobseeker(jobseeker);
			users.setUserNama(jobseeker.getJobseekerNama());
			users.setUserRole(athrole);
			Sessions.getCurrent().setAttribute("usersTemp", users);
			return users;
		}

	}

	public static void insertToTab(final Tabbox iframe, final AthMenu menu) {

		if (menu.getUrl() != null) {
			try {
				Window window = (Window) Class.forName(menu.getUrl().trim())
						.newInstance();
				insertToTab(iframe, menu, window);
				return;
			} catch (Exception e) {

			}
		}

		List<Tab> tabs = iframe.getTabs().getChildren();
		boolean ada = false;
		for (Tab tab : tabs) {
			if (tab.getLabel().equalsIgnoreCase(menu.getLabel())) {
				ada = true;
				tab.setSelected(true);
				break;
			}
		}
		if (!ada) {
			final Tab tab = new Tab(menu.getLabel());

			tab.setImage("/include/img/menu-none.png");
			tab.addEventListener("onClick", new EventListener() {

				@Override
				public void onEvent(Event arg0) throws Exception {
					System.out.println("============================= "
							+ tab.getLabel() + " ================ clicked");
				}
			});
			tab.setClosable(true);
			tab.setSelected(true);
			iframe.getTabs().appendChild(tab);
			Tabpanel tabpanel = new Tabpanel();
			MyIframe include = new MyIframe(menu.getUrl().trim());
			include.setWidth("100%");
			include.setHeight("100%");
			tabpanel.appendChild(include);
			iframe.getTabpanels().appendChild(tabpanel);
		}
	}

	@SuppressWarnings("unchecked")
	public static void insertToTab(final Tabbox iframe, final AthMenu menu,
			final Window window) {
		window.setHeight("100%");
		window.setWidth("100%");
		window.setTitle("");
		window.setClosable(false);

		List<Tab> tabs = iframe.getTabs().getChildren();
		boolean ada = false;
		for (Tab tab : tabs) {
			if (tab.getLabel().equalsIgnoreCase(menu.getLabel())) {
				ada = true;
				tab.setSelected(true);
				break;
			}
		}
		if (!ada) {
			final Tab tab = new Tab(menu.getLabel());

			tab.setImage("/include/img/menu-none.png");
			tab.addEventListener("onClick", new EventListener() {

				@Override
				public void onEvent(Event arg0) throws Exception {
					System.out.println("============================= "
							+ tab.getLabel() + " ================ clicked");
				}
			});
			tab.setClosable(true);
			tab.setSelected(true);
			iframe.getTabs().appendChild(tab);
			Tabpanel tabpanel = new Tabpanel();
			tabpanel.appendChild(window);
			iframe.getTabpanels().appendChild(tabpanel);
		}
	}

	@SuppressWarnings("deprecation")
	public static void launchMenu(AthMenu menu) throws Exception {

		if (!CommonPrivilages.checkPrevilages(CommonPrivilages.READ)) {
			Messagebox.show(
					"Maaf, anda tidak diperkenankan untuk mengakses menu ini",
					"Peringatan", Messagebox.OK, Messagebox.INFORMATION);
			return;
		}

		Tabbox iframe = (Tabbox) Sessions.getCurrent().getAttribute("iframe");
		if (menu.getUrl().trim().equals("rubah_password")) {
			ChangePasswordWindow window = new ChangePasswordWindow();
			System.out.println("cc" + window + "cc" + menu);
			window.setVisible(true);
			Common.insertToTab(iframe, menu, window);

		} else if (menu.getUrl().trim().equals("laporanAlbumMahasiswaWisuda")) {
			// LaporanAlbumMahasiswaWisuda window = new
			// LaporanAlbumMahasiswaWisuda();
			// Common.insertToTab(iframe, menu, window, login);

		} else {
			Common.insertToTab(iframe, menu);
		}

	}

	/*** FOR INSERT ENV ZKOSS ***/
	public static void showNotify(String msg){
        Clients.showNotification(msg,"info",null,null,1000);
    }
	public static void clear(Component comp) {
		if (comp == null || comp.getChildren() == null)
			return;
		int list = comp.getChildren().size();
		for (int i = 0; i < list; i++) {
			((Component) comp.getChildren().get(0)).detach();
		}
	}

	@SuppressWarnings("unchecked")
	public static void initCombos(Combobox[] comboboxs, String[] properties,
			Class[] classes) {
		for (int i = 0; i < comboboxs.length; i++) {
			insertCombo(comboboxs[i], properties[i], classes[i]);
		}
	}

	@SuppressWarnings("unchecked")
	public static void initCombos(Combobox[] comboboxs, String[] properties,
			Class[] classes, Criterion[] criterions) {
		for (int i = 0; i < comboboxs.length; i++) {
			insertCombo(comboboxs[i], properties[i], classes[i], criterions[i]);
		}
	}

	@SuppressWarnings("unchecked")
	public static void insertCombo(Combobox combobox, String property,
			Class clazz, Criterion... criterions) {
		Criteria criteria = HibernateUtil.currentSession()
				.createCriteria(clazz);
		if (criterions != null) {
			for (Criterion criterion : criterions) {
				if (criterion != null) {
					criteria.add(criterion);
				}
			}
		}
		List list = criteria.list();
		insertComboItems(combobox, property, list);
	}

	@SuppressWarnings("unchecked")
	public static void insertCombo(Combobox combobox, String property,
			Class clazz, Criterion criterion) {
		Criteria criteria = HibernateUtil.currentSession()
				.createCriteria(clazz);
		criteria.add(criterion);
		List list = criteria.list();
		insertComboItems(combobox, property, list);
	}

	@SuppressWarnings("unchecked")
	public static void insertCombo(Combobox combobox, String property,
			Class clazz) {
		if (combobox == null)
			return;
		Criteria criteria = HibernateUtil.currentSession()
				.createCriteria(clazz);

		List list = criteria.list();
		insertComboItems(combobox, property, list);
	}

	@SuppressWarnings("unchecked")
	public static void insertComboItems(Combobox combo, String property,
			List items) {
		Common.clear(combo);
		if (items.size() == 0)
			return;
		Class clazz = items.get(0).getClass();
		ClassMetadata metadata = null;
		if (!clazz.equals(CommonVO.class)) {
			metadata = HibernateUtil.getClassMetadata(clazz);
		}
		for (Object o : items) {
			Comboitem comboitem = new Comboitem();
			if (o instanceof CommonVO) {
				CommonVO oo = (CommonVO) o;
				comboitem.setLabel(oo.getName());
				comboitem.setValue(oo.getId());
			} else {
				comboitem.setLabel(property.equals("") ? o + "" : ""
						+ metadata.getPropertyValue(o, property,
								EntityMode.POJO));
				comboitem.setValue(o);
			}
			combo.appendChild(comboitem);
		}
	}

	@SuppressWarnings("unchecked")
	public static void selectComboItem(Combobox combo, Object value) {
		if (value == null) {
			combo.setSelectedItem(null);
			return;
		}

		List<Comboitem> list = combo.getItems();
		ClassMetadata metadata = HibernateUtil.getClassMetadata(value
				.getClass());
		Serializable identityvalue = null;
		if (!(value instanceof String) && !(value instanceof Integer)
				&& !(value instanceof Double) && !(value instanceof Date)) {
			identityvalue = metadata.getIdentifier(value, EntityMode.POJO);
		}

		for (Comboitem comboitem : list) {
			if ((value instanceof String) || (value instanceof Integer)
					|| (value instanceof Double) || (value instanceof Date)) {
				// System.out.println("value = " + value
				// + ", comboitem.getValue() = " + comboitem.getValue());
				if (value.equals(comboitem.getValue())) {
					combo.setSelectedItem(comboitem);
				}
			} else {
				try {
					Serializable id = metadata.getIdentifier(
							comboitem.getValue(), EntityMode.POJO);
					// System.out.println("identityvalue = " + identityvalue
					// + ", id = " + id);

					if (identityvalue.equals(id)) {
						combo.setSelectedItem(comboitem);
					}
				} catch (Exception e) {
				}
			}
		}
	}

	/*** FOR PAGING ***/
	public static void initPaging(Paging paging, EventListener eventListener) {
		initPaging(null, paging, eventListener);
	}

	public static void initPaging(Criteria criteria, Paging paging) {
		initPaging(criteria, paging, null);
	}

	public static void initPaging(Criteria criteria, Paging paging,
			EventListener eventListener) {
		if (paging == null) {
			return;
		}
		if (eventListener == null) {
			paging.setPageSize(Common.ROWS_COUNT_ON_PAGE);
			paging.setMold("os");
			int size = 10000;

			try {
				size = ((Number) criteria
						.setProjection(Projections.count("id")).uniqueResult())
						.intValue();
			} catch (Exception e) {
				e.printStackTrace();
			}
			// System.out.println("size = " + size);
			paging.setTotalSize(size);
			paging.setVisible(size > Common.ROWS_COUNT_ON_PAGE);
			try {
				((South) paging.getParent())
						.setHeight(size > Common.ROWS_COUNT_ON_PAGE ? "30px"
								: "0px");
			} catch (Exception e) {
				// e.printStackTrace();
			}
		} else {
			paging.addEventListener("onPaging", eventListener);
		}
	}
}
